setwd("/Users/efraimshine/Desktop/rna_seq/TCGA/")
Warning: The working directory was changed to /Users/efraimshine/Desktop/rna_seq/TCGA inside a notebook chunk. The working directory will be reset when the chunk is finished running. Use the knitr root.dir option in the setup chunk to change the working directory for notebook chunks.
data("XenaData")
write.csv(XenaData, "00_tblXenaHubInfo.csv")

## step 5-a
GeneExpectedCnt_toil = XenaGenerate(subset = XenaHostNames == "toilHub") %>%
  XenaFilter(filterCohorts = "TCGA TARGET GTEx") %>%
  XenaFilter(filterDatasets = "TcgaTargetGtex_gene_expected_count");
XenaQuery(GeneExpectedCnt_toil) %>%
  XenaDownload(destdir = "./")
This will check url status, please be patient.
All downloaded files will under directory ./.
The 'trans_slash' option is FALSE, keep same directory structure as Xena.
Creating directories for datasets...
.//TcgaTargetGtex_gene_expected_count.gz, the file has been download!
library("UCSCXenaTools")
=========================================================================================
UCSCXenaTools version 1.4.8
Project URL: https://github.com/ropensci/UCSCXenaTools
Usages: https://cran.r-project.org/web/packages/UCSCXenaTools/vignettes/USCSXenaTools.html

If you use it in published research, please cite:
Wang et al., (2019). The UCSCXenaTools R package: a toolkit for accessing genomics data
  from UCSC Xena platform, from cancer multi-omics to single-cell RNA-seq.
  Journal of Open Source Software, 4(40), 1627, https://doi.org/10.21105/joss.01627
=========================================================================================
                              --Enjoy it--
library("R.utils")
Loading required package: R.oo
Loading required package: R.methodsS3
R.methodsS3 v1.8.2 (2022-06-13 22:00:14 UTC) successfully loaded. See ?R.methodsS3 for help.
R.oo v1.27.0 (2024-11-01 18:00:02 UTC) successfully loaded. See ?R.oo for help.

Attaching package: ‘R.oo’

The following object is masked from ‘package:R.methodsS3’:

    throw

The following objects are masked from ‘package:methods’:

    getClasses, getMethods

The following objects are masked from ‘package:base’:

    attach, detach, load, save

R.utils v2.12.3 (2023-11-18 01:00:02 UTC) successfully loaded. See ?R.utils for help.

Attaching package: ‘R.utils’

The following object is masked from ‘package:utils’:

    timestamp

The following objects are masked from ‘package:base’:

    cat, commandArgs, getOption, isOpen, nullfile, parse, use, warnings
library("dplyr")

Attaching package: ‘dplyr’

The following objects are masked from ‘package:stats’:

    filter, lag

The following objects are masked from ‘package:base’:

    intersect, setdiff, setequal, union
library("data.table")
Registered S3 method overwritten by 'data.table':
  method           from
  print.data.table     
data.table 1.16.4 using 4 threads (see ?getDTthreads).  Latest news: r-datatable.com

Attaching package: ‘data.table’

The following objects are masked from ‘package:dplyr’:

    between, first, last
library("readr")
library("edgeR")
Loading required package: limma
setwd("/Users/efraimshine/Desktop/rna_seq/TCGA")
Warning: The working directory was changed to /Users/efraimshine/Desktop/rna_seq/TCGA inside a notebook chunk. The working directory will be reset when the chunk is finished running. Use the knitr root.dir option in the setup chunk to change the working directory for notebook chunks.
samples_gene_expression = fread("TcgaTargetGtex_gene_expected_count.gz");
|--------------------------------------------------|
|==================================================|
Warning: Discarded single-line footer: <<ENSG00000171757.15 5.8056  8.2322  7.2623  4.5850  3.9165  7.3622  7.2790  7.6363  6.7690  6.7673  4.4019  6.5567  5.1735  5.9430  5.1526  6.8088  6.3393  6.0659  8.9498  5.6185  5.4757  6.3232  8.1606  8.5839  5.5689  7.5140  9.1020  5.2593  6.4981  5.4886  6.2024  6.1106  6.6073  6.4373  3.1699  6.0870  6.9506  4.4182  9.3345  7.4155  8.0521  4.5503  6.5664  4.7214  5.5928  6.5469  5.5680  6.3293  4.3125  5.3377  8.5245  4.6809  4.4770  7.9141  6.9937  5.4621  6.8374  4.4790  6.7127  7.8719  7.0444  3.0000  4.9411  4.8354  5.4835  8.5906  8.9245  1.6508  7.761>>
setwd("/Users/efraimshine/Desktop/rna_seq/TCGA")
Warning: The working directory was changed to /Users/efraimshine/Desktop/rna_seq/TCGA inside a notebook chunk. The working directory will be reset when the chunk is finished running. Use the knitr root.dir option in the setup chunk to change the working directory for notebook chunks.
create_back_transformed_df <- function(sample_file, gene_expression_data) {
  # Read the sample list
  list_data <- read.csv(sample_file, header = FALSE)
  vector_data <- list_data$V1

  # Filter out excluded samples
  filtered_vector <- vector_data[vector_data %in% colnames(gene_expression_data)]


  # Filter the gene expression data
  filtered_df <- gene_expression_data %>% select("sample", all_of(filtered_vector))
  rownames(filtered_df) <- filtered_df$sample
  
  # Backtransform the numeric columns
  backtransformed_df <- filtered_df %>%
    mutate(across(where(is.numeric), ~ 2^. - 1))
  rownames(backtransformed_df) <- backtransformed_df$sample
  # Set row names and remove the first column

  return(backtransformed_df)
}

g6pd_deleted_samples_file <- "g6pd_deleted_samples.csv"
#sample_file_g6pd_control_normal_expression_file = "g6pd_normal_samples_control_group.csv"
sample_file_g6pd_control_normal_expression_file = "G6PD_normal_cancer_type_based_selection.csv"

# Call the function and store the result
g6pd_del_df <- create_back_transformed_df(g6pd_deleted_samples_file, samples_gene_expression)
g6pd_normal_control_df <- create_back_transformed_df(sample_file_g6pd_control_normal_expression_file, samples_gene_expression)
head(g6pd_normal_control_df[, 1:10], 10)
head(g6pd_del_df[, 1:10], 10)
g6pd_normal_control_df
g6pd_del_df
NA
# checking control data frame samples
# ctr_rnames <- colnames(g6pd_normal_control_df[,-1])
# ctr_orig_df <- read.csv("/Users/efraimshine/Desktop/rna_seq/TCGA/g6pd_high_exp_1.75to2.25_z_score_samples_names.csv")
# ctr_orig_df
# ctr_rnames
# common_names <- intersect(ctr_rnames,ctr_orig_df$Sample.ID)
# common_names
# print(common_names)
g6pd_normal_control_df
# Define the arguments
library("data.table")
library("readr")
library("dplyr")
library("edgeR")




# Add prefixes to column names
colnames(g6pd_del_df) <- paste0("DELE_", colnames(g6pd_del_df))
colnames(g6pd_normal_control_df) <- paste0("NORM_", colnames(g6pd_normal_control_df))

# Combine the data frames by rows
merged_df <- merge(g6pd_del_df, g6pd_normal_control_df, by.x="DELE_sample",by.y = "NORM_sample")
colnames(merged_df)[colnames(merged_df) == "DELE_sample"] <- "sample"
# rownames(merged_df) <- merged_df$sample
# merged_df$sample <- NULL

# rownames(g6pd_del_df) <- g6pd_del_df$DELE_sample
# g6pd_del_df$DELE_sample <- NULL

# rownames(g6pd_normal_control_df) <- g6pd_normal_control_df$NORM_sample
# g6pd_normal_control_df$NORM_sample <- NULL
merged_df
NA
NA
merged_df_rownames <- merged_df[,-1]
rownames(merged_df_rownames) <- merged_df$sample
# merged_df_round_vector <- lapply(merged_df_rownames, round , digits = 2)
# merged_df_rownames_rounded <- data.frame(merged_df_round_vector)
#rownames(merged_df_rownames_rounded) <- rownames(merged_df_rownames)
merged_df_rownames_rounded <- merged_df_rownames %>% mutate(across(where(is.numeric), round, digits = 0))
Warning: There was 1 warning in `mutate()`.
ℹ In argument: `across(where(is.numeric), round, digits = 0)`.
Caused by warning:
! The `...` argument of `across()` is deprecated as of dplyr 1.1.0.
Supply arguments directly to `.fns` through an anonymous function instead.

  # Previously
  across(a:b, mean, na.rm = TRUE)

  # Now
  across(a:b, \(x) mean(x, na.rm = TRUE))
This warning is displayed once every 8 hours.
Call `lifecycle::last_lifecycle_warnings()` to see where this warning was generated.
matrix_for_deseq <- as.matrix(merged_df_rownames_rounded)
rownames(matrix_for_deseq) <- rownames(merged_df_rownames_rounded)
merged_df_rownames
merged_df_rownames_rounded

setwd("/Users/efraimshine/Desktop/rna_seq/TCGA")
Warning: The working directory was changed to /Users/efraimshine/Desktop/rna_seq/TCGA inside a notebook chunk. The working directory will be reset when the chunk is finished running. Use the knitr root.dir option in the setup chunk to change the working directory for notebook chunks.
metadata <- data.frame(sample_names <- colnames(merged_df[,-1]))
#row.names(metadata) <- colnames(merged_df)
metadata <- mutate(metadata, G6PD_STATUS = ifelse(row_number() <= length(g6pd_del_df[,-1]), "del", "normal"))

metadata_rnames <- metadata
rownames(metadata_rnames) <- metadata$sample_names....colnames.merged_df
metadata_rnames$sample_names....colnames.merged_df....1.. <- NULL
metadata
metadata_rnames
NA
NA
NA
# metadata <- mutate(metadata, G6PD_STATUS = ifelse(row_number() <= length(g6pd_del_df[,-1]), "del", "normal"))

setwd("/Users/efraimshine/Desktop/rna_seq/TCGA")
Warning: The working directory was changed to /Users/efraimshine/Desktop/rna_seq/TCGA inside a notebook chunk. The working directory will be reset when the chunk is finished running. Use the knitr root.dir option in the setup chunk to change the working directory for notebook chunks.
metadata_rnames_for_info_merge <- metadata_rnames
metadata_rnames_for_info_merge
#expanding meta data information for analysis of g6pd deleted samples VS 200 g6pd normal samples from the center of g6pd expression information
library("dplyr")

#samples_info_deleted_vs_200_patients <- read_tsv("g6pd_samples_info_deleted_vs_two_hundreds.tsv") 
#samples_info_deleted_vs_200_patients <- as.data.frame(samples_info_deleted_vs_200_patients) %>% dplyr::select(`Sample ID`,`Cancer Type`,`Cancer Type Detailed`)

samples_info_deleted_vs_cancer_type_based_selection <- read_tsv("info_g6pd_deleted_vs_normal_cancer_type_based_selection.tsv") 
Rows: 1539 Columns: 63── Column specification ──────────────────────────────────────────────────────────────────────────────────────────────────────────
Delimiter: "\t"
chr (43): Study ID, Patient ID, Sample ID, Neoplasm Disease Stage American Joint Committee on Cancer Code, American Joint Comm...
dbl (20): Diagnosis Age, Aneuploidy Score, Last Communication Contact from Initial Pathologic Diagnosis Date, Birth from Initi...
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
samples_info_deleted_vs_cancer_type_based_selection <- as.data.frame(samples_info_deleted_vs_cancer_type_based_selection) %>% dplyr::select(`Sample ID`,`Cancer Type`,`Cancer Type Detailed`,`Study ID`)


# merege metadata with info df
row.names(metadata_rnames_for_info_merge) <- gsub("^[^_]*_", "", row.names(metadata_rnames_for_info_merge))

metadata_rnames_merged_with_info <- merge(metadata_rnames_for_info_merge,samples_info_deleted_vs_cancer_type_based_selection, by.x = "row.names", by.y = "Sample ID",all.x = TRUE)
row.names(metadata_rnames_merged_with_info) <- metadata_rnames_merged_with_info$Row.names
metadata_rnames_merged_with_info$Row.names <- NULL
metadata_rnames_merged_with_info <- metadata_rnames_merged_with_info[order(metadata_rnames_merged_with_info$G6PD_STATUS), ]
metadata_rnames_merged_with_info_orderd <- metadata_rnames_merged_with_info[match(row.names(metadata_rnames_for_info_merge), row.names(metadata_rnames_merged_with_info)), ]

row.names(metadata_rnames_merged_with_info_orderd) <- row.names(metadata_rnames)
colnames(metadata_rnames_merged_with_info_orderd)[2] <- "cancer_type"
colnames(metadata_rnames_merged_with_info_orderd)[3] <- "cancer_type_detailed"

metadata_rnames_merged_with_info_orderd$cancer_type <- as.factor(metadata_rnames_merged_with_info_orderd$cancer_type)
metadata_rnames_merged_with_info_orderd$cancer_type_detailed <- as.factor(metadata_rnames_merged_with_info_orderd$cancer_type_detailed)
metadata_rnames_merged_with_info
metadata_rnames_merged_with_info_orderd
NA
colnames(metadata_rnames_merged_with_info_orderd)[4] <- "study_ID"
metadata_rnames_merged_with_info_orderd$cancer_type <- as.factor(metadata_rnames_merged_with_info_orderd$cancer_type)
metadata_rnames_merged_with_info_orderd$cancer_type_detailed <- as.factor(metadata_rnames_merged_with_info_orderd$cancer_type_detailed)
metadata_rnames_merged_with_info_orderd$G6PD_STATUS <- as.factor(metadata_rnames_merged_with_info_orderd$G6PD_STATUS)
metadata_rnames_merged_with_info_orderd$`Study ID` <- as.factor(metadata_rnames_merged_with_info_orderd$`study_ID`)
metadata_rnames_merged_with_info
metadata_rnames_merged_with_info_orderd
names_df <- as.data.frame(data_col <- colnames(matrix_for_deseq),metadatarows <- rownames(metadata_rnames))
names_df$`data_col <- colnames(matrix_for_deseq)` == rownames(names_df)
   [1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
  [25] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
  [49] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
  [73] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
  [97] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
 [121] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
 [145] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
 [169] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
 [193] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
 [217] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
 [241] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
 [265] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
 [289] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
 [313] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
 [337] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
 [361] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
 [385] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
 [409] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
 [433] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
 [457] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
 [481] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
 [505] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
 [529] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
 [553] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
 [577] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
 [601] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
 [625] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
 [649] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
 [673] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
 [697] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
 [721] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
 [745] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
 [769] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
 [793] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
 [817] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
 [841] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
 [865] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
 [889] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
 [913] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
 [937] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
 [961] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
 [985] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
 [ reached getOption("max.print") -- omitted 428 entries ]
names_df
unique_cancers <- unique(metadata_rnames_merged_with_info_orderd$cancer_type)

results_list <- list()

for (cancer in unique_cancers) {
  subset_meta <- metadata_rnames_merged_with_info_orderd[metadata_rnames_merged_with_info_orderd$cancer_type == cancer, ]
  subset_counts <- matrix_for_deseq[, rownames(subset_meta)]
  
  dds_loop <- DESeqDataSetFromMatrix(countData = subset_counts,
                                colData = subset_meta,
                                design = ~ G6PD_STATUS)
  dds_loop <- DESeq(dds_loop)
  
  results_list[[cancer]] <- results(dds_loop, contrast = c("G6PD_STATUS", "del", "normal"))
}
converting counts to integer mode
estimating size factors
estimating dispersions
gene-wise dispersion estimates
mean-dispersion relationship
final dispersion estimates
fitting model and testing
-- replacing outliers and refitting for 18811 genes
-- DESeq argument 'minReplicatesForReplace' = 7 
-- original counts are preserved in counts(dds)
estimating dispersions
fitting model and testing
converting counts to integer mode
estimating size factors
estimating dispersions
gene-wise dispersion estimates
mean-dispersion relationship
final dispersion estimates
fitting model and testing
-- replacing outliers and refitting for 22176 genes
-- DESeq argument 'minReplicatesForReplace' = 7 
-- original counts are preserved in counts(dds)
estimating dispersions
fitting model and testing
converting counts to integer mode
estimating size factors
estimating dispersions
gene-wise dispersion estimates
mean-dispersion relationship
final dispersion estimates
fitting model and testing
-- replacing outliers and refitting for 3719 genes
-- DESeq argument 'minReplicatesForReplace' = 7 
-- original counts are preserved in counts(dds)
estimating dispersions
fitting model and testing
converting counts to integer mode
estimating size factors
estimating dispersions
gene-wise dispersion estimates
mean-dispersion relationship
final dispersion estimates
fitting model and testing
-- replacing outliers and refitting for 22515 genes
-- DESeq argument 'minReplicatesForReplace' = 7 
-- original counts are preserved in counts(dds)
estimating dispersions
fitting model and testing
converting counts to integer mode
estimating size factors
estimating dispersions
gene-wise dispersion estimates
mean-dispersion relationship
final dispersion estimates
fitting model and testing
converting counts to integer mode
estimating size factors
estimating dispersions
gene-wise dispersion estimates
mean-dispersion relationship
final dispersion estimates
fitting model and testing
-- replacing outliers and refitting for 3271 genes
-- DESeq argument 'minReplicatesForReplace' = 7 
-- original counts are preserved in counts(dds)
estimating dispersions
fitting model and testing
converting counts to integer mode
estimating size factors
estimating dispersions
gene-wise dispersion estimates
mean-dispersion relationship
final dispersion estimates
fitting model and testing
-- replacing outliers and refitting for 19251 genes
-- DESeq argument 'minReplicatesForReplace' = 7 
-- original counts are preserved in counts(dds)
estimating dispersions
fitting model and testing
converting counts to integer mode
estimating size factors
estimating dispersions
gene-wise dispersion estimates
mean-dispersion relationship
final dispersion estimates
fitting model and testing
-- replacing outliers and refitting for 2076 genes
-- DESeq argument 'minReplicatesForReplace' = 7 
-- original counts are preserved in counts(dds)
estimating dispersions
fitting model and testing
converting counts to integer mode
estimating size factors
estimating dispersions
gene-wise dispersion estimates
mean-dispersion relationship
final dispersion estimates
fitting model and testing
-- replacing outliers and refitting for 2299 genes
-- DESeq argument 'minReplicatesForReplace' = 7 
-- original counts are preserved in counts(dds)
estimating dispersions
fitting model and testing
converting counts to integer mode
estimating size factors
estimating dispersions
gene-wise dispersion estimates
mean-dispersion relationship
final dispersion estimates
fitting model and testing
-- replacing outliers and refitting for 2671 genes
-- DESeq argument 'minReplicatesForReplace' = 7 
-- original counts are preserved in counts(dds)
estimating dispersions
fitting model and testing
converting counts to integer mode
estimating size factors
estimating dispersions
gene-wise dispersion estimates
mean-dispersion relationship
final dispersion estimates
fitting model and testing
-- replacing outliers and refitting for 2497 genes
-- DESeq argument 'minReplicatesForReplace' = 7 
-- original counts are preserved in counts(dds)
estimating dispersions
fitting model and testing
converting counts to integer mode
estimating size factors
estimating dispersions
gene-wise dispersion estimates
mean-dispersion relationship
final dispersion estimates
fitting model and testing
-- replacing outliers and refitting for 23669 genes
-- DESeq argument 'minReplicatesForReplace' = 7 
-- original counts are preserved in counts(dds)
estimating dispersions
fitting model and testing
converting counts to integer mode
estimating size factors
estimating dispersions
gene-wise dispersion estimates
mean-dispersion relationship
final dispersion estimates
fitting model and testing
-- replacing outliers and refitting for 3018 genes
-- DESeq argument 'minReplicatesForReplace' = 7 
-- original counts are preserved in counts(dds)
estimating dispersions
fitting model and testing
converting counts to integer mode
estimating size factors
estimating dispersions
gene-wise dispersion estimates
mean-dispersion relationship
final dispersion estimates
fitting model and testing
-- replacing outliers and refitting for 1024 genes
-- DESeq argument 'minReplicatesForReplace' = 7 
-- original counts are preserved in counts(dds)
estimating dispersions
fitting model and testing
converting counts to integer mode
estimating size factors
estimating dispersions
gene-wise dispersion estimates
mean-dispersion relationship
final dispersion estimates
fitting model and testing
-- replacing outliers and refitting for 23071 genes
-- DESeq argument 'minReplicatesForReplace' = 7 
-- original counts are preserved in counts(dds)
estimating dispersions
fitting model and testing
converting counts to integer mode
estimating size factors
estimating dispersions
gene-wise dispersion estimates
mean-dispersion relationship
final dispersion estimates
fitting model and testing
-- replacing outliers and refitting for 23429 genes
-- DESeq argument 'minReplicatesForReplace' = 7 
-- original counts are preserved in counts(dds)
estimating dispersions
fitting model and testing
# Load required libraries
library(DESeq2)
library(clusterProfiler)
library(org.Hs.eg.db)
library(ggplot2)

# Initialize lists to store results
filtered_results_list <- list()
GO_enrichment_results <- list()

# Loop through each cancer type in results_list
for (cancer in names(results_list)) {
  
  # Extract results (already a DESeqResults object)
  res05 <- results_list[[cancer]]
  
  # Summary of DEGs
  cat("\nSummary for", cancer, ":\n")
  print(summary(res05))
  
  # Generate MA plot
  png(paste0("MA_plot_", cancer, ".png"), width = 800, height = 600)
  plotMA(res05, ylim=c(-2,2), main=paste("MA Plot -", cancer))
  dev.off()
  
  # Remove NA values
  sigs <- na.omit(res05)
  
  # Filter significantly differentially expressed genes (padj < 0.05 & baseMean > 50)
  sigs <- sigs[sigs$padj < 0.05 & sigs$baseMean > 0,]
  
  # Store filtered results
  filtered_results_list[[cancer]] <- sigs
  
  # Extract genes with log2FoldChange > 0.5
  genes_to_test <- rownames(sigs[sigs$log2FoldChange > 0,])
  
  # Remove Ensembl version numbers (if present)
  genes_to_test_no_dots <- gsub("\\..*", "", genes_to_test)
  
  # Perform GO enrichment analysis (if there are genes to test)
  if (length(genes_to_test_no_dots) > 0) {
    GO_results <- enrichGO(gene = genes_to_test_no_dots, 
                           OrgDb = "org.Hs.eg.db", 
                           keyType = "ENSEMBL", 
                           ont = "BP", 
                           pAdjustMethod = "BH",
                           pvalueCutoff = 0.05)
    
    # Convert to dataframe and store results
    GO_enrichment_results[[cancer]] <- as.data.frame(GO_results)
  }
}

Summary for Adrenocortical Carcinoma :

out of 24498 with nonzero total read count
adjusted p-value < 0.1
LFC > 0 (up)       : 23, 0.094%
LFC < 0 (down)     : 118, 0.48%
outliers [1]       : 0, 0%
low counts [2]     : 12484, 51%
(mean count < 12)
[1] see 'cooksCutoff' argument of ?results
[2] see 'independentFiltering' argument of ?results

NULL

Summary for Bladder Cancer :

out of 29831 with nonzero total read count
adjusted p-value < 0.1
LFC > 0 (up)       : 55, 0.18%
LFC < 0 (down)     : 338, 1.1%
outliers [1]       : 0, 0%
low counts [2]     : 17672, 59%
(mean count < 18)
[1] see 'cooksCutoff' argument of ?results
[2] see 'independentFiltering' argument of ?results

NULL

Summary for Breast Cancer :

out of 32003 with nonzero total read count
adjusted p-value < 0.1
LFC > 0 (up)       : 23, 0.072%
LFC < 0 (down)     : 32, 0.1%
outliers [1]       : 381, 1.2%
low counts [2]     : 13474, 42%
(mean count < 1)
[1] see 'cooksCutoff' argument of ?results
[2] see 'independentFiltering' argument of ?results

NULL

Summary for Colorectal Cancer :

out of 28413 with nonzero total read count
adjusted p-value < 0.1
LFC > 0 (up)       : 199, 0.7%
LFC < 0 (down)     : 294, 1%
outliers [1]       : 0, 0%
low counts [2]     : 16250, 57%
(mean count < 13)
[1] see 'cooksCutoff' argument of ?results
[2] see 'independentFiltering' argument of ?results

NULL

Summary for Mature B-Cell Neoplasms :

out of 22424 with nonzero total read count
adjusted p-value < 0.1
LFC > 0 (up)       : 156, 0.7%
LFC < 0 (down)     : 151, 0.67%
outliers [1]       : 488, 2.2%
low counts [2]     : 8767, 39%
(mean count < 4)
[1] see 'cooksCutoff' argument of ?results
[2] see 'independentFiltering' argument of ?results

NULL

Summary for Esophagogastric Cancer :

out of 33539 with nonzero total read count
adjusted p-value < 0.1
LFC > 0 (up)       : 18, 0.054%
LFC < 0 (down)     : 24, 0.072%
outliers [1]       : 664, 2%
low counts [2]     : 17135, 51%
(mean count < 5)
[1] see 'cooksCutoff' argument of ?results
[2] see 'independentFiltering' argument of ?results

NULL

Summary for Glioblastoma :

out of 27196 with nonzero total read count
adjusted p-value < 0.1
LFC > 0 (up)       : 191, 0.7%
LFC < 0 (down)     : 274, 1%
outliers [1]       : 0, 0%
low counts [2]     : 12906, 47%
(mean count < 5)
[1] see 'cooksCutoff' argument of ?results
[2] see 'independentFiltering' argument of ?results

NULL

Summary for Head and Neck Cancer :

out of 30595 with nonzero total read count
adjusted p-value < 0.1
LFC > 0 (up)       : 1136, 3.7%
LFC < 0 (down)     : 2044, 6.7%
outliers [1]       : 0, 0%
low counts [2]     : 15811, 52%
(mean count < 3)
[1] see 'cooksCutoff' argument of ?results
[2] see 'independentFiltering' argument of ?results

NULL

Summary for Hepatobiliary Cancer :

out of 27633 with nonzero total read count
adjusted p-value < 0.1
LFC > 0 (up)       : 2, 0.0072%
LFC < 0 (down)     : 40, 0.14%
outliers [1]       : 331, 1.2%
low counts [2]     : 11533, 42%
(mean count < 1)
[1] see 'cooksCutoff' argument of ?results
[2] see 'independentFiltering' argument of ?results

NULL

Summary for Non-Small Cell Lung Cancer :

out of 30237 with nonzero total read count
adjusted p-value < 0.1
LFC > 0 (up)       : 24, 0.079%
LFC < 0 (down)     : 25, 0.083%
outliers [1]       : 614, 2%
low counts [2]     : 13208, 44%
(mean count < 2)
[1] see 'cooksCutoff' argument of ?results
[2] see 'independentFiltering' argument of ?results

NULL

Summary for Ovarian Epithelial Tumor :

out of 30526 with nonzero total read count
adjusted p-value < 0.1
LFC > 0 (up)       : 269, 0.88%
LFC < 0 (down)     : 332, 1.1%
outliers [1]       : 0, 0%
low counts [2]     : 14019, 46%
(mean count < 4)
[1] see 'cooksCutoff' argument of ?results
[2] see 'independentFiltering' argument of ?results

NULL

Summary for Prostate Cancer :

out of 29672 with nonzero total read count
adjusted p-value < 0.1
LFC > 0 (up)       : 8, 0.027%
LFC < 0 (down)     : 30, 0.1%
outliers [1]       : 0, 0%
low counts [2]     : 14182, 48%
(mean count < 3)
[1] see 'cooksCutoff' argument of ?results
[2] see 'independentFiltering' argument of ?results

NULL

Summary for Sarcoma :

out of 28910 with nonzero total read count
adjusted p-value < 0.1
LFC > 0 (up)       : 162, 0.56%
LFC < 0 (down)     : 141, 0.49%
outliers [1]       : 1152, 4%
low counts [2]     : 11467, 40%
(mean count < 2)
[1] see 'cooksCutoff' argument of ?results
[2] see 'independentFiltering' argument of ?results

NULL

Summary for Thyroid Cancer :

out of 29102 with nonzero total read count
adjusted p-value < 0.1
LFC > 0 (up)       : 11, 0.038%
LFC < 0 (down)     : 6, 0.021%
outliers [1]       : 180, 0.62%
low counts [2]     : 11631, 40%
(mean count < 1)
[1] see 'cooksCutoff' argument of ?results
[2] see 'independentFiltering' argument of ?results

NULL

Summary for Endometrial Cancer :

out of 29480 with nonzero total read count
adjusted p-value < 0.1
LFC > 0 (up)       : 22, 0.075%
LFC < 0 (down)     : 53, 0.18%
outliers [1]       : 0, 0%
low counts [2]     : 15315, 52%
(mean count < 7)
[1] see 'cooksCutoff' argument of ?results
[2] see 'independentFiltering' argument of ?results

NULL

Summary for Melanoma :

out of 29825 with nonzero total read count
adjusted p-value < 0.1
LFC > 0 (up)       : 4, 0.013%
LFC < 0 (down)     : 83, 0.28%
outliers [1]       : 0, 0%
low counts [2]     : 15945, 53%
(mean count < 7)
[1] see 'cooksCutoff' argument of ?results
[2] see 'independentFiltering' argument of ?results

NULL
# Save results
save(filtered_results_list, GO_enrichment_results, file = "DEG_GO_results.RData")

# Print message when done
cat("Analysis complete! Filtered DEGs and GO enrichment results are saved.\n")
Analysis complete! Filtered DEGs and GO enrichment results are saved.
multi_results <- load("DEG_GO_results.RData")
GO_enrichment_results[["Mature B-Cell Neoplasms"]]
library("DESeq2")
dds_multi <- DESeqDataSetFromMatrix(countData = matrix_for_deseq,
                              colData = metadata_rnames_merged_with_info_orderd,
                              design = ~ cancer_type + G6PD_STATUS + cancer_type:G6PD_STATUS)
converting counts to integer mode
  Note: levels of factors in the design contain characters other than
  letters, numbers, '_' and '.'. It is recommended (but not required) to use
  only letters, numbers, and delimiters '_' or '.', as these are safe characters
  for column names in R. [This is a message, not a warning or an error]
dds_multi$G6PD_STATUS <- relevel(dds_multi$G6PD_STATUS, ref = "normal")
dds_multi
class: DESeqDataSet 
dim: 38608 1428 
metadata(1): version
assays(1): counts
rownames(38608): ENSG00000000938.12 ENSG00000000971.15 ... ENSGR0000280767.2 ENSGR0000281849.2
rowData names(0):
colnames(1428): DELE_TCGA-OR-A5LC-01 DELE_TCGA-DK-A1AE-01 ... NORM_TCGA-ZS-A9CD-01 NORM_TCGA-ZS-A9CF-01
colData names(5): G6PD_STATUS cancer_type cancer_type_detailed study_ID Study ID
dds_multi <- DESeq(dds_multi)
estimating size factors
  Note: levels of factors in the design contain characters other than
  letters, numbers, '_' and '.'. It is recommended (but not required) to use
  only letters, numbers, and delimiters '_' or '.', as these are safe characters
  for column names in R. [This is a message, not a warning or an error]
estimating dispersions
gene-wise dispersion estimates
mean-dispersion relationship
  Note: levels of factors in the design contain characters other than
  letters, numbers, '_' and '.'. It is recommended (but not required) to use
  only letters, numbers, and delimiters '_' or '.', as these are safe characters
  for column names in R. [This is a message, not a warning or an error]
final dispersion estimates
fitting model and testing
1615 rows did not converge in beta, labelled in mcols(object)$betaConv. Use larger maxit argument with nbinomWaldTest
  Note: levels of factors in the design contain characters other than
  letters, numbers, '_' and '.'. It is recommended (but not required) to use
  only letters, numbers, and delimiters '_' or '.', as these are safe characters
  for column names in R. [This is a message, not a warning or an error]
-- replacing outliers and refitting for 22497 genes
-- DESeq argument 'minReplicatesForReplace' = 7 
-- original counts are preserved in counts(dds)
estimating dispersions
Error: vector memory limit of 16.0 Gb reached, see mem.maxVSize()
resultsNames(dds)
resOrdered <- res[order(res$pvalue),]
summary(res)
sum(res$padj < 0.05, na.rm=TRUE)
res05 <- results(dds, alpha=0.05)
summary(res05)
plotMA(res, ylim=c(-2,2))
resSig <- subset(resOrdered, padj < 0.05)
resSig
#filtering the results
results_df <- read.csv("/Users/efraimshine/Desktop/rna_seq/TCGA/G6PD_abovepadj_0.05.csv")
results_df
results_filtered <- results_df %>% filter(log2FoldChange >0 ,padj < 0.05)
results_filtered
write.csv(as.data.frame(results_filtered), 
          file="/Users/efraimshine/Desktop/rna_seq/TCGA/deseq2_res_g6pd/G6PD_results_filtered.csv")
# clustering
library(clusterProfiler)
library(org.Hs.eg.db)
library(AnnotationDbi)
# results as in tutorial notebook
sigs <- na.omit(res)
sigs
sigs <- sigs[sigs$padj < 0.05 & sigs$baseMean > 50,]
sigs
genes_to_test <- rownames(sigs[sigs$log2FoldChange > 0.5,]) 

genes_to_test_no_dots <- gsub("\\..*", "", genes_to_test)
#GO analysis
GO_results <- enrichGO(gene = genes_to_test_no_dots, OrgDb = "org.Hs.eg.db", keyType = "ENSEMBL", ont = "BP")
as.data.frame(GO_results)
fit <- plot(barplot(GO_results, showCategory = 20))
png("out.png", res = 250, width = 1400, height = 1800)
print(fit)
dev.off()
# GO_results <- enricher()
# as.data.frame(GO_results)
# # prepaer meta data for multi factor analysis 
# metadata_rnames_merged_with_info_orderd
# metadata_rnames_merged_with_info_orderd$G6PD_STATUS <- factor(metadata_rnames_merged_with_info_orderd$G6PD_STATUS)
# table(metadata_rnames_merged_with_info_orderd$cancer_type, metadata_rnames_merged_with_info_orderd$G6PD_STATUS)
# metadata_rnames_merged_with_info_orderd$cancer_type <- droplevels(metadata_rnames_merged_with_info_orderd$cancer_type)
# metadata_rnames_merged_with_info_orderd$G6PD_STATUS <- droplevels(metadata_rnames_merged_with_info_orderd$G6PD_STATUS)
# metadata_rnames_merged_with_info_orderd

Add a new chunk by clicking the Insert Chunk button on the toolbar or by pressing Cmd+Option+I.

When you save the notebook, an HTML file containing the code and output will be saved alongside it (click the Preview button or press Cmd+Shift+K to preview the HTML file).

The preview shows you a rendered HTML copy of the contents of the editor. Consequently, unlike Knit, Preview does not run any R code chunks. Instead, the output of the chunk when it was last run in the editor is displayed.

LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKCmBgYHtyfQpzZXR3ZCgiL1VzZXJzL2VmcmFpbXNoaW5lL0Rlc2t0b3Avcm5hX3NlcS9UQ0dBLyIpCgpkYXRhKCJYZW5hRGF0YSIpCndyaXRlLmNzdihYZW5hRGF0YSwgIjAwX3RibFhlbmFIdWJJbmZvLmNzdiIpCgojIyBzdGVwIDUtYQpHZW5lRXhwZWN0ZWRDbnRfdG9pbCA9IFhlbmFHZW5lcmF0ZShzdWJzZXQgPSBYZW5hSG9zdE5hbWVzID09ICJ0b2lsSHViIikgJT4lCiAgWGVuYUZpbHRlcihmaWx0ZXJDb2hvcnRzID0gIlRDR0EgVEFSR0VUIEdURXgiKSAlPiUKICBYZW5hRmlsdGVyKGZpbHRlckRhdGFzZXRzID0gIlRjZ2FUYXJnZXRHdGV4X2dlbmVfZXhwZWN0ZWRfY291bnQiKTsKWGVuYVF1ZXJ5KEdlbmVFeHBlY3RlZENudF90b2lsKSAlPiUKICBYZW5hRG93bmxvYWQoZGVzdGRpciA9ICIuLyIpCmBgYAoKCmBgYHtyfQpsaWJyYXJ5KCJVQ1NDWGVuYVRvb2xzIikKbGlicmFyeSgiUi51dGlscyIpCmxpYnJhcnkoImRwbHlyIikKbGlicmFyeSgiZGF0YS50YWJsZSIpCmxpYnJhcnkoInJlYWRyIikKbGlicmFyeSgiZWRnZVIiKQpzZXR3ZCgiL1VzZXJzL2VmcmFpbXNoaW5lL0Rlc2t0b3Avcm5hX3NlcS9UQ0dBIikKc2FtcGxlc19nZW5lX2V4cHJlc3Npb24gPSBmcmVhZCgiVGNnYVRhcmdldEd0ZXhfZ2VuZV9leHBlY3RlZF9jb3VudC5neiIpOwoKYGBgCgpgYGB7cn0Kc2V0d2QoIi9Vc2Vycy9lZnJhaW1zaGluZS9EZXNrdG9wL3JuYV9zZXEvVENHQSIpCmNyZWF0ZV9iYWNrX3RyYW5zZm9ybWVkX2RmIDwtIGZ1bmN0aW9uKHNhbXBsZV9maWxlLCBnZW5lX2V4cHJlc3Npb25fZGF0YSkgewogICMgUmVhZCB0aGUgc2FtcGxlIGxpc3QKICBsaXN0X2RhdGEgPC0gcmVhZC5jc3Yoc2FtcGxlX2ZpbGUsIGhlYWRlciA9IEZBTFNFKQogIHZlY3Rvcl9kYXRhIDwtIGxpc3RfZGF0YSRWMQoKICAjIEZpbHRlciBvdXQgZXhjbHVkZWQgc2FtcGxlcwogIGZpbHRlcmVkX3ZlY3RvciA8LSB2ZWN0b3JfZGF0YVt2ZWN0b3JfZGF0YSAlaW4lIGNvbG5hbWVzKGdlbmVfZXhwcmVzc2lvbl9kYXRhKV0KCgogICMgRmlsdGVyIHRoZSBnZW5lIGV4cHJlc3Npb24gZGF0YQogIGZpbHRlcmVkX2RmIDwtIGdlbmVfZXhwcmVzc2lvbl9kYXRhICU+JSBzZWxlY3QoInNhbXBsZSIsIGFsbF9vZihmaWx0ZXJlZF92ZWN0b3IpKQogIHJvd25hbWVzKGZpbHRlcmVkX2RmKSA8LSBmaWx0ZXJlZF9kZiRzYW1wbGUKICAKICAjIEJhY2t0cmFuc2Zvcm0gdGhlIG51bWVyaWMgY29sdW1ucwogIGJhY2t0cmFuc2Zvcm1lZF9kZiA8LSBmaWx0ZXJlZF9kZiAlPiUKICAgIG11dGF0ZShhY3Jvc3Mod2hlcmUoaXMubnVtZXJpYyksIH4gMl4uIC0gMSkpCiAgcm93bmFtZXMoYmFja3RyYW5zZm9ybWVkX2RmKSA8LSBiYWNrdHJhbnNmb3JtZWRfZGYkc2FtcGxlCiAgIyBTZXQgcm93IG5hbWVzIGFuZCByZW1vdmUgdGhlIGZpcnN0IGNvbHVtbgoKICByZXR1cm4oYmFja3RyYW5zZm9ybWVkX2RmKQp9CgpnNnBkX2RlbGV0ZWRfc2FtcGxlc19maWxlIDwtICJnNnBkX2RlbGV0ZWRfc2FtcGxlcy5jc3YiCiNzYW1wbGVfZmlsZV9nNnBkX2NvbnRyb2xfbm9ybWFsX2V4cHJlc3Npb25fZmlsZSA9ICJnNnBkX25vcm1hbF9zYW1wbGVzX2NvbnRyb2xfZ3JvdXAuY3N2IgpzYW1wbGVfZmlsZV9nNnBkX2NvbnRyb2xfbm9ybWFsX2V4cHJlc3Npb25fZmlsZSA9ICJHNlBEX25vcm1hbF9jYW5jZXJfdHlwZV9iYXNlZF9zZWxlY3Rpb24uY3N2IgoKIyBDYWxsIHRoZSBmdW5jdGlvbiBhbmQgc3RvcmUgdGhlIHJlc3VsdApnNnBkX2RlbF9kZiA8LSBjcmVhdGVfYmFja190cmFuc2Zvcm1lZF9kZihnNnBkX2RlbGV0ZWRfc2FtcGxlc19maWxlLCBzYW1wbGVzX2dlbmVfZXhwcmVzc2lvbikKZzZwZF9ub3JtYWxfY29udHJvbF9kZiA8LSBjcmVhdGVfYmFja190cmFuc2Zvcm1lZF9kZihzYW1wbGVfZmlsZV9nNnBkX2NvbnRyb2xfbm9ybWFsX2V4cHJlc3Npb25fZmlsZSwgc2FtcGxlc19nZW5lX2V4cHJlc3Npb24pCmhlYWQoZzZwZF9ub3JtYWxfY29udHJvbF9kZlssIDE6MTBdLCAxMCkKaGVhZChnNnBkX2RlbF9kZlssIDE6MTBdLCAxMCkKZzZwZF9ub3JtYWxfY29udHJvbF9kZgpnNnBkX2RlbF9kZgoKYGBgCmBgYHtyfQojIGNoZWNraW5nIGNvbnRyb2wgZGF0YSBmcmFtZSBzYW1wbGVzCiMgY3RyX3JuYW1lcyA8LSBjb2xuYW1lcyhnNnBkX25vcm1hbF9jb250cm9sX2RmWywtMV0pCiMgY3RyX29yaWdfZGYgPC0gcmVhZC5jc3YoIi9Vc2Vycy9lZnJhaW1zaGluZS9EZXNrdG9wL3JuYV9zZXEvVENHQS9nNnBkX2hpZ2hfZXhwXzEuNzV0bzIuMjVfel9zY29yZV9zYW1wbGVzX25hbWVzLmNzdiIpCiMgY3RyX29yaWdfZGYKIyBjdHJfcm5hbWVzCiMgY29tbW9uX25hbWVzIDwtIGludGVyc2VjdChjdHJfcm5hbWVzLGN0cl9vcmlnX2RmJFNhbXBsZS5JRCkKIyBjb21tb25fbmFtZXMKIyBwcmludChjb21tb25fbmFtZXMpCmBgYAoKCgpgYGB7cn0KIyBEZWZpbmUgdGhlIGFyZ3VtZW50cwpsaWJyYXJ5KCJkYXRhLnRhYmxlIikKbGlicmFyeSgicmVhZHIiKQpsaWJyYXJ5KCJkcGx5ciIpCmxpYnJhcnkoImVkZ2VSIikKCgoKCiMgQWRkIHByZWZpeGVzIHRvIGNvbHVtbiBuYW1lcwpjb2xuYW1lcyhnNnBkX2RlbF9kZikgPC0gcGFzdGUwKCJERUxFXyIsIGNvbG5hbWVzKGc2cGRfZGVsX2RmKSkKY29sbmFtZXMoZzZwZF9ub3JtYWxfY29udHJvbF9kZikgPC0gcGFzdGUwKCJOT1JNXyIsIGNvbG5hbWVzKGc2cGRfbm9ybWFsX2NvbnRyb2xfZGYpKQoKIyBDb21iaW5lIHRoZSBkYXRhIGZyYW1lcyBieSByb3dzCm1lcmdlZF9kZiA8LSBtZXJnZShnNnBkX2RlbF9kZiwgZzZwZF9ub3JtYWxfY29udHJvbF9kZiwgYnkueD0iREVMRV9zYW1wbGUiLGJ5LnkgPSAiTk9STV9zYW1wbGUiKQpjb2xuYW1lcyhtZXJnZWRfZGYpW2NvbG5hbWVzKG1lcmdlZF9kZikgPT0gIkRFTEVfc2FtcGxlIl0gPC0gInNhbXBsZSIKIyByb3duYW1lcyhtZXJnZWRfZGYpIDwtIG1lcmdlZF9kZiRzYW1wbGUKIyBtZXJnZWRfZGYkc2FtcGxlIDwtIE5VTEwKCiMgcm93bmFtZXMoZzZwZF9kZWxfZGYpIDwtIGc2cGRfZGVsX2RmJERFTEVfc2FtcGxlCiMgZzZwZF9kZWxfZGYkREVMRV9zYW1wbGUgPC0gTlVMTAoKIyByb3duYW1lcyhnNnBkX25vcm1hbF9jb250cm9sX2RmKSA8LSBnNnBkX25vcm1hbF9jb250cm9sX2RmJE5PUk1fc2FtcGxlCiMgZzZwZF9ub3JtYWxfY29udHJvbF9kZiROT1JNX3NhbXBsZSA8LSBOVUxMCm1lcmdlZF9kZgoKCmBgYAoKCmBgYHtyfQptZXJnZWRfZGZfcm93bmFtZXMgPC0gbWVyZ2VkX2RmWywtMV0Kcm93bmFtZXMobWVyZ2VkX2RmX3Jvd25hbWVzKSA8LSBtZXJnZWRfZGYkc2FtcGxlCiMgbWVyZ2VkX2RmX3JvdW5kX3ZlY3RvciA8LSBsYXBwbHkobWVyZ2VkX2RmX3Jvd25hbWVzLCByb3VuZCAsIGRpZ2l0cyA9IDIpCiMgbWVyZ2VkX2RmX3Jvd25hbWVzX3JvdW5kZWQgPC0gZGF0YS5mcmFtZShtZXJnZWRfZGZfcm91bmRfdmVjdG9yKQojcm93bmFtZXMobWVyZ2VkX2RmX3Jvd25hbWVzX3JvdW5kZWQpIDwtIHJvd25hbWVzKG1lcmdlZF9kZl9yb3duYW1lcykKbWVyZ2VkX2RmX3Jvd25hbWVzX3JvdW5kZWQgPC0gbWVyZ2VkX2RmX3Jvd25hbWVzICU+JSBtdXRhdGUoYWNyb3NzKHdoZXJlKGlzLm51bWVyaWMpLCByb3VuZCwgZGlnaXRzID0gMCkpCm1hdHJpeF9mb3JfZGVzZXEgPC0gYXMubWF0cml4KG1lcmdlZF9kZl9yb3duYW1lc19yb3VuZGVkKQpyb3duYW1lcyhtYXRyaXhfZm9yX2Rlc2VxKSA8LSByb3duYW1lcyhtZXJnZWRfZGZfcm93bmFtZXNfcm91bmRlZCkKbWVyZ2VkX2RmX3Jvd25hbWVzCm1lcmdlZF9kZl9yb3duYW1lc19yb3VuZGVkCmBgYAoKCgpgYGB7cn0KCnNldHdkKCIvVXNlcnMvZWZyYWltc2hpbmUvRGVza3RvcC9ybmFfc2VxL1RDR0EiKQoKbWV0YWRhdGEgPC0gZGF0YS5mcmFtZShzYW1wbGVfbmFtZXMgPC0gY29sbmFtZXMobWVyZ2VkX2RmWywtMV0pKQojcm93Lm5hbWVzKG1ldGFkYXRhKSA8LSBjb2xuYW1lcyhtZXJnZWRfZGYpCm1ldGFkYXRhIDwtIG11dGF0ZShtZXRhZGF0YSwgRzZQRF9TVEFUVVMgPSBpZmVsc2Uocm93X251bWJlcigpIDw9IGxlbmd0aChnNnBkX2RlbF9kZlssLTFdKSwgImRlbCIsICJub3JtYWwiKSkKCm1ldGFkYXRhX3JuYW1lcyA8LSBtZXRhZGF0YQpyb3duYW1lcyhtZXRhZGF0YV9ybmFtZXMpIDwtIG1ldGFkYXRhJHNhbXBsZV9uYW1lcy4uLi5jb2xuYW1lcy5tZXJnZWRfZGYKbWV0YWRhdGFfcm5hbWVzJHNhbXBsZV9uYW1lcy4uLi5jb2xuYW1lcy5tZXJnZWRfZGYuLi4uMS4uIDwtIE5VTEwKbWV0YWRhdGEKbWV0YWRhdGFfcm5hbWVzCgoKCmBgYAoKYGBge3J9CiMgbWV0YWRhdGEgPC0gbXV0YXRlKG1ldGFkYXRhLCBHNlBEX1NUQVRVUyA9IGlmZWxzZShyb3dfbnVtYmVyKCkgPD0gbGVuZ3RoKGc2cGRfZGVsX2RmWywtMV0pLCAiZGVsIiwgIm5vcm1hbCIpKQoKc2V0d2QoIi9Vc2Vycy9lZnJhaW1zaGluZS9EZXNrdG9wL3JuYV9zZXEvVENHQSIpCm1ldGFkYXRhX3JuYW1lc19mb3JfaW5mb19tZXJnZSA8LSBtZXRhZGF0YV9ybmFtZXMKbWV0YWRhdGFfcm5hbWVzX2Zvcl9pbmZvX21lcmdlCiNleHBhbmRpbmcgbWV0YSBkYXRhIGluZm9ybWF0aW9uIGZvciBhbmFseXNpcyBvZiBnNnBkIGRlbGV0ZWQgc2FtcGxlcyBWUyAyMDAgZzZwZCBub3JtYWwgc2FtcGxlcyBmcm9tIHRoZSBjZW50ZXIgb2YgZzZwZCBleHByZXNzaW9uIGluZm9ybWF0aW9uCmxpYnJhcnkoImRwbHlyIikKCiNzYW1wbGVzX2luZm9fZGVsZXRlZF92c18yMDBfcGF0aWVudHMgPC0gcmVhZF90c3YoImc2cGRfc2FtcGxlc19pbmZvX2RlbGV0ZWRfdnNfdHdvX2h1bmRyZWRzLnRzdiIpIAojc2FtcGxlc19pbmZvX2RlbGV0ZWRfdnNfMjAwX3BhdGllbnRzIDwtIGFzLmRhdGEuZnJhbWUoc2FtcGxlc19pbmZvX2RlbGV0ZWRfdnNfMjAwX3BhdGllbnRzKSAlPiUgZHBseXI6OnNlbGVjdChgU2FtcGxlIElEYCxgQ2FuY2VyIFR5cGVgLGBDYW5jZXIgVHlwZSBEZXRhaWxlZGApCgpzYW1wbGVzX2luZm9fZGVsZXRlZF92c19jYW5jZXJfdHlwZV9iYXNlZF9zZWxlY3Rpb24gPC0gcmVhZF90c3YoImluZm9fZzZwZF9kZWxldGVkX3ZzX25vcm1hbF9jYW5jZXJfdHlwZV9iYXNlZF9zZWxlY3Rpb24udHN2IikgCnNhbXBsZXNfaW5mb19kZWxldGVkX3ZzX2NhbmNlcl90eXBlX2Jhc2VkX3NlbGVjdGlvbiA8LSBhcy5kYXRhLmZyYW1lKHNhbXBsZXNfaW5mb19kZWxldGVkX3ZzX2NhbmNlcl90eXBlX2Jhc2VkX3NlbGVjdGlvbikgJT4lIGRwbHlyOjpzZWxlY3QoYFNhbXBsZSBJRGAsYENhbmNlciBUeXBlYCxgQ2FuY2VyIFR5cGUgRGV0YWlsZWRgLGBTdHVkeSBJRGApCgoKIyBtZXJlZ2UgbWV0YWRhdGEgd2l0aCBpbmZvIGRmCnJvdy5uYW1lcyhtZXRhZGF0YV9ybmFtZXNfZm9yX2luZm9fbWVyZ2UpIDwtIGdzdWIoIl5bXl9dKl8iLCAiIiwgcm93Lm5hbWVzKG1ldGFkYXRhX3JuYW1lc19mb3JfaW5mb19tZXJnZSkpCgptZXRhZGF0YV9ybmFtZXNfbWVyZ2VkX3dpdGhfaW5mbyA8LSBtZXJnZShtZXRhZGF0YV9ybmFtZXNfZm9yX2luZm9fbWVyZ2Usc2FtcGxlc19pbmZvX2RlbGV0ZWRfdnNfY2FuY2VyX3R5cGVfYmFzZWRfc2VsZWN0aW9uLCBieS54ID0gInJvdy5uYW1lcyIsIGJ5LnkgPSAiU2FtcGxlIElEIixhbGwueCA9IFRSVUUpCnJvdy5uYW1lcyhtZXRhZGF0YV9ybmFtZXNfbWVyZ2VkX3dpdGhfaW5mbykgPC0gbWV0YWRhdGFfcm5hbWVzX21lcmdlZF93aXRoX2luZm8kUm93Lm5hbWVzCm1ldGFkYXRhX3JuYW1lc19tZXJnZWRfd2l0aF9pbmZvJFJvdy5uYW1lcyA8LSBOVUxMCm1ldGFkYXRhX3JuYW1lc19tZXJnZWRfd2l0aF9pbmZvIDwtIG1ldGFkYXRhX3JuYW1lc19tZXJnZWRfd2l0aF9pbmZvW29yZGVyKG1ldGFkYXRhX3JuYW1lc19tZXJnZWRfd2l0aF9pbmZvJEc2UERfU1RBVFVTKSwgXQptZXRhZGF0YV9ybmFtZXNfbWVyZ2VkX3dpdGhfaW5mb19vcmRlcmQgPC0gbWV0YWRhdGFfcm5hbWVzX21lcmdlZF93aXRoX2luZm9bbWF0Y2gocm93Lm5hbWVzKG1ldGFkYXRhX3JuYW1lc19mb3JfaW5mb19tZXJnZSksIHJvdy5uYW1lcyhtZXRhZGF0YV9ybmFtZXNfbWVyZ2VkX3dpdGhfaW5mbykpLCBdCgpyb3cubmFtZXMobWV0YWRhdGFfcm5hbWVzX21lcmdlZF93aXRoX2luZm9fb3JkZXJkKSA8LSByb3cubmFtZXMobWV0YWRhdGFfcm5hbWVzKQpjb2xuYW1lcyhtZXRhZGF0YV9ybmFtZXNfbWVyZ2VkX3dpdGhfaW5mb19vcmRlcmQpWzJdIDwtICJjYW5jZXJfdHlwZSIKY29sbmFtZXMobWV0YWRhdGFfcm5hbWVzX21lcmdlZF93aXRoX2luZm9fb3JkZXJkKVszXSA8LSAiY2FuY2VyX3R5cGVfZGV0YWlsZWQiCgoKCmBgYAoKYGBge3J9CmNvbG5hbWVzKG1ldGFkYXRhX3JuYW1lc19tZXJnZWRfd2l0aF9pbmZvX29yZGVyZClbNF0gPC0gInN0dWR5X0lEIgptZXRhZGF0YV9ybmFtZXNfbWVyZ2VkX3dpdGhfaW5mb19vcmRlcmQkY2FuY2VyX3R5cGUgPC0gYXMuZmFjdG9yKG1ldGFkYXRhX3JuYW1lc19tZXJnZWRfd2l0aF9pbmZvX29yZGVyZCRjYW5jZXJfdHlwZSkKbWV0YWRhdGFfcm5hbWVzX21lcmdlZF93aXRoX2luZm9fb3JkZXJkJGNhbmNlcl90eXBlX2RldGFpbGVkIDwtIGFzLmZhY3RvcihtZXRhZGF0YV9ybmFtZXNfbWVyZ2VkX3dpdGhfaW5mb19vcmRlcmQkY2FuY2VyX3R5cGVfZGV0YWlsZWQpCm1ldGFkYXRhX3JuYW1lc19tZXJnZWRfd2l0aF9pbmZvX29yZGVyZCRHNlBEX1NUQVRVUyA8LSBhcy5mYWN0b3IobWV0YWRhdGFfcm5hbWVzX21lcmdlZF93aXRoX2luZm9fb3JkZXJkJEc2UERfU1RBVFVTKQptZXRhZGF0YV9ybmFtZXNfbWVyZ2VkX3dpdGhfaW5mb19vcmRlcmQkYFN0dWR5IElEYCA8LSBhcy5mYWN0b3IobWV0YWRhdGFfcm5hbWVzX21lcmdlZF93aXRoX2luZm9fb3JkZXJkJGBzdHVkeV9JRGApCm1ldGFkYXRhX3JuYW1lc19tZXJnZWRfd2l0aF9pbmZvCm1ldGFkYXRhX3JuYW1lc19tZXJnZWRfd2l0aF9pbmZvX29yZGVyZApgYGAKCgoKYGBge3J9Cm5hbWVzX2RmIDwtIGFzLmRhdGEuZnJhbWUoZGF0YV9jb2wgPC0gY29sbmFtZXMobWF0cml4X2Zvcl9kZXNlcSksbWV0YWRhdGFyb3dzIDwtIHJvd25hbWVzKG1ldGFkYXRhX3JuYW1lcykpCm5hbWVzX2RmJGBkYXRhX2NvbCA8LSBjb2xuYW1lcyhtYXRyaXhfZm9yX2Rlc2VxKWAgPT0gcm93bmFtZXMobmFtZXNfZGYpCm5hbWVzX2RmCmBgYApgYGB7cn0KdW5pcXVlX2NhbmNlcnMgPC0gdW5pcXVlKG1ldGFkYXRhX3JuYW1lc19tZXJnZWRfd2l0aF9pbmZvX29yZGVyZCRjYW5jZXJfdHlwZSkKCnJlc3VsdHNfbGlzdCA8LSBsaXN0KCkKCmZvciAoY2FuY2VyIGluIHVuaXF1ZV9jYW5jZXJzKSB7CiAgc3Vic2V0X21ldGEgPC0gbWV0YWRhdGFfcm5hbWVzX21lcmdlZF93aXRoX2luZm9fb3JkZXJkW21ldGFkYXRhX3JuYW1lc19tZXJnZWRfd2l0aF9pbmZvX29yZGVyZCRjYW5jZXJfdHlwZSA9PSBjYW5jZXIsIF0KICBzdWJzZXRfY291bnRzIDwtIG1hdHJpeF9mb3JfZGVzZXFbLCByb3duYW1lcyhzdWJzZXRfbWV0YSldCiAgCiAgZGRzX2xvb3AgPC0gREVTZXFEYXRhU2V0RnJvbU1hdHJpeChjb3VudERhdGEgPSBzdWJzZXRfY291bnRzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbERhdGEgPSBzdWJzZXRfbWV0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXNpZ24gPSB+IEc2UERfU1RBVFVTKQogIGRkc19sb29wIDwtIERFU2VxKGRkc19sb29wKQogIAogIHJlc3VsdHNfbGlzdFtbY2FuY2VyXV0gPC0gcmVzdWx0cyhkZHNfbG9vcCwgY29udHJhc3QgPSBjKCJHNlBEX1NUQVRVUyIsICJkZWwiLCAibm9ybWFsIikpCn0KYGBgCgpgYGB7cn0KIyBMb2FkIHJlcXVpcmVkIGxpYnJhcmllcwpsaWJyYXJ5KERFU2VxMikKbGlicmFyeShjbHVzdGVyUHJvZmlsZXIpCmxpYnJhcnkob3JnLkhzLmVnLmRiKQpsaWJyYXJ5KGdncGxvdDIpCgojIEluaXRpYWxpemUgbGlzdHMgdG8gc3RvcmUgcmVzdWx0cwpmaWx0ZXJlZF9yZXN1bHRzX2xpc3QgPC0gbGlzdCgpCkdPX2VucmljaG1lbnRfcmVzdWx0cyA8LSBsaXN0KCkKCiMgTG9vcCB0aHJvdWdoIGVhY2ggY2FuY2VyIHR5cGUgaW4gcmVzdWx0c19saXN0CmZvciAoY2FuY2VyIGluIG5hbWVzKHJlc3VsdHNfbGlzdCkpIHsKICAKICAjIEV4dHJhY3QgcmVzdWx0cyAoYWxyZWFkeSBhIERFU2VxUmVzdWx0cyBvYmplY3QpCiAgcmVzMDUgPC0gcmVzdWx0c19saXN0W1tjYW5jZXJdXQogIAogICMgU3VtbWFyeSBvZiBERUdzCiAgY2F0KCJcblN1bW1hcnkgZm9yIiwgY2FuY2VyLCAiOlxuIikKICBwcmludChzdW1tYXJ5KHJlczA1KSkKICAKICAjIEdlbmVyYXRlIE1BIHBsb3QKICBwbmcocGFzdGUwKCJNQV9wbG90XyIsIGNhbmNlciwgIi5wbmciKSwgd2lkdGggPSA4MDAsIGhlaWdodCA9IDYwMCkKICBwbG90TUEocmVzMDUsIHlsaW09YygtMiwyKSwgbWFpbj1wYXN0ZSgiTUEgUGxvdCAtIiwgY2FuY2VyKSkKICBkZXYub2ZmKCkKICAKICAjIFJlbW92ZSBOQSB2YWx1ZXMKICBzaWdzIDwtIG5hLm9taXQocmVzMDUpCiAgCiAgIyBGaWx0ZXIgc2lnbmlmaWNhbnRseSBkaWZmZXJlbnRpYWxseSBleHByZXNzZWQgZ2VuZXMgKHBhZGogPCAwLjA1ICYgYmFzZU1lYW4gPiA1MCkKICBzaWdzIDwtIHNpZ3Nbc2lncyRwYWRqIDwgMC4wNSAmIHNpZ3MkYmFzZU1lYW4gPiAwLF0KICAKICAjIFN0b3JlIGZpbHRlcmVkIHJlc3VsdHMKICBmaWx0ZXJlZF9yZXN1bHRzX2xpc3RbW2NhbmNlcl1dIDwtIHNpZ3MKICAKICAjIEV4dHJhY3QgZ2VuZXMgd2l0aCBsb2cyRm9sZENoYW5nZSA+IDAuNQogIGdlbmVzX3RvX3Rlc3QgPC0gcm93bmFtZXMoc2lnc1tzaWdzJGxvZzJGb2xkQ2hhbmdlID4gMCxdKQogIAogICMgUmVtb3ZlIEVuc2VtYmwgdmVyc2lvbiBudW1iZXJzIChpZiBwcmVzZW50KQogIGdlbmVzX3RvX3Rlc3Rfbm9fZG90cyA8LSBnc3ViKCJcXC4uKiIsICIiLCBnZW5lc190b190ZXN0KQogIAogICMgUGVyZm9ybSBHTyBlbnJpY2htZW50IGFuYWx5c2lzIChpZiB0aGVyZSBhcmUgZ2VuZXMgdG8gdGVzdCkKICBpZiAobGVuZ3RoKGdlbmVzX3RvX3Rlc3Rfbm9fZG90cykgPiAwKSB7CiAgICBHT19yZXN1bHRzIDwtIGVucmljaEdPKGdlbmUgPSBnZW5lc190b190ZXN0X25vX2RvdHMsIAogICAgICAgICAgICAgICAgICAgICAgICAgICBPcmdEYiA9ICJvcmcuSHMuZWcuZGIiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAga2V5VHlwZSA9ICJFTlNFTUJMIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIG9udCA9ICJCUCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICBwQWRqdXN0TWV0aG9kID0gIkJIIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgcHZhbHVlQ3V0b2ZmID0gMC4wNSkKICAgIAogICAgIyBDb252ZXJ0IHRvIGRhdGFmcmFtZSBhbmQgc3RvcmUgcmVzdWx0cwogICAgR09fZW5yaWNobWVudF9yZXN1bHRzW1tjYW5jZXJdXSA8LSBhcy5kYXRhLmZyYW1lKEdPX3Jlc3VsdHMpCiAgfQp9CgojIFNhdmUgcmVzdWx0cwpzYXZlKGZpbHRlcmVkX3Jlc3VsdHNfbGlzdCwgR09fZW5yaWNobWVudF9yZXN1bHRzLCBmaWxlID0gIkRFR19HT19yZXN1bHRzLlJEYXRhIikKCiMgUHJpbnQgbWVzc2FnZSB3aGVuIGRvbmUKY2F0KCJBbmFseXNpcyBjb21wbGV0ZSEgRmlsdGVyZWQgREVHcyBhbmQgR08gZW5yaWNobWVudCByZXN1bHRzIGFyZSBzYXZlZC5cbiIpCgpgYGAKYGBge3J9Cm11bHRpX3Jlc3VsdHMgPC0gbG9hZCgiREVHX0dPX3Jlc3VsdHMuUkRhdGEiKQpHT19lbnJpY2htZW50X3Jlc3VsdHNbWyJNYXR1cmUgQi1DZWxsIE5lb3BsYXNtcyJdXQpgYGAKCgpgYGB7cn0KIyBsaWJyYXJ5KCJERVNlcTIiKQojIGRkc19tdWx0aSA8LSBERVNlcURhdGFTZXRGcm9tTWF0cml4KGNvdW50RGF0YSA9IG1hdHJpeF9mb3JfZGVzZXEsCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sRGF0YSA9IG1ldGFkYXRhX3JuYW1lc19tZXJnZWRfd2l0aF9pbmZvX29yZGVyZCwKIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXNpZ24gPSB+IGNhbmNlcl90eXBlICsgRzZQRF9TVEFUVVMgKyBjYW5jZXJfdHlwZTpHNlBEX1NUQVRVUykKIyBkZHNfbXVsdGkkRzZQRF9TVEFUVVMgPC0gcmVsZXZlbChkZHNfbXVsdGkkRzZQRF9TVEFUVVMsIHJlZiA9ICJub3JtYWwiKQojIGRkc19tdWx0aQpgYGAKCgoKYGBge3J9CiMgZGRzX211bHRpIDwtIERFU2VxKGRkc19tdWx0aSkKIyAjIHJlcyA8LSByZXN1bHRzKGRkc19tdWx0aSkKIyAjIGRkc19tdWx0aQpgYGAKCmBgYHtyfQpyZXN1bHRzTmFtZXMoZGRzKQoKYGBgCmBgYHtyfQpyZXNPcmRlcmVkIDwtIHJlc1tvcmRlcihyZXMkcHZhbHVlKSxdCnN1bW1hcnkocmVzKQpgYGAKYGBge3J9CnN1bShyZXMkcGFkaiA8IDAuMDUsIG5hLnJtPVRSVUUpCmBgYApgYGB7cn0KcmVzMDUgPC0gcmVzdWx0cyhkZHMsIGFscGhhPTAuMDUpCnN1bW1hcnkocmVzMDUpCmBgYApgYGB7cn0KcGxvdE1BKHJlcywgeWxpbT1jKC0yLDIpKQpgYGAKYGBge3J9CnJlc1NpZyA8LSBzdWJzZXQocmVzT3JkZXJlZCwgcGFkaiA8IDAuMDUpCnJlc1NpZwoKYGBgCmBgYHtyfQojZmlsdGVyaW5nIHRoZSByZXN1bHRzCnJlc3VsdHNfZGYgPC0gcmVhZC5jc3YoIi9Vc2Vycy9lZnJhaW1zaGluZS9EZXNrdG9wL3JuYV9zZXEvVENHQS9HNlBEX2Fib3ZlcGFkal8wLjA1LmNzdiIpCnJlc3VsdHNfZGYKcmVzdWx0c19maWx0ZXJlZCA8LSByZXN1bHRzX2RmICU+JSBmaWx0ZXIobG9nMkZvbGRDaGFuZ2UgPjAgLHBhZGogPCAwLjA1KQpyZXN1bHRzX2ZpbHRlcmVkCndyaXRlLmNzdihhcy5kYXRhLmZyYW1lKHJlc3VsdHNfZmlsdGVyZWQpLCAKICAgICAgICAgIGZpbGU9Ii9Vc2Vycy9lZnJhaW1zaGluZS9EZXNrdG9wL3JuYV9zZXEvVENHQS9kZXNlcTJfcmVzX2c2cGQvRzZQRF9yZXN1bHRzX2ZpbHRlcmVkLmNzdiIpCmBgYApgYGB7cn0KIyBjbHVzdGVyaW5nCmxpYnJhcnkoY2x1c3RlclByb2ZpbGVyKQpsaWJyYXJ5KG9yZy5Icy5lZy5kYikKbGlicmFyeShBbm5vdGF0aW9uRGJpKQpgYGAKCgpgYGB7cn0KIyByZXN1bHRzIGFzIGluIHR1dG9yaWFsIG5vdGVib29rCnNpZ3MgPC0gbmEub21pdChyZXMpCnNpZ3MKc2lncyA8LSBzaWdzW3NpZ3MkcGFkaiA8IDAuMDUgJiBzaWdzJGJhc2VNZWFuID4gNTAsXQpzaWdzCmdlbmVzX3RvX3Rlc3QgPC0gcm93bmFtZXMoc2lnc1tzaWdzJGxvZzJGb2xkQ2hhbmdlID4gMC41LF0pIAoKZ2VuZXNfdG9fdGVzdF9ub19kb3RzIDwtIGdzdWIoIlxcLi4qIiwgIiIsIGdlbmVzX3RvX3Rlc3QpCgoKCgoKYGBgCmBgYHtyfQojR08gYW5hbHlzaXMKR09fcmVzdWx0cyA8LSBlbnJpY2hHTyhnZW5lID0gZ2VuZXNfdG9fdGVzdF9ub19kb3RzLCBPcmdEYiA9ICJvcmcuSHMuZWcuZGIiLCBrZXlUeXBlID0gIkVOU0VNQkwiLCBvbnQgPSAiQlAiKQphcy5kYXRhLmZyYW1lKEdPX3Jlc3VsdHMpCgoKYGBgCmBgYHtyfQpmaXQgPC0gcGxvdChiYXJwbG90KEdPX3Jlc3VsdHMsIHNob3dDYXRlZ29yeSA9IDIwKSkKcG5nKCJvdXQucG5nIiwgcmVzID0gMjUwLCB3aWR0aCA9IDE0MDAsIGhlaWdodCA9IDE4MDApCnByaW50KGZpdCkKZGV2Lm9mZigpCgpgYGAKCgpgYGB7cn0KIyBHT19yZXN1bHRzIDwtIGVucmljaGVyKCkKIyBhcy5kYXRhLmZyYW1lKEdPX3Jlc3VsdHMpCmBgYAoKCmBgYHtyfQojICMgcHJlcGFlciBtZXRhIGRhdGEgZm9yIG11bHRpIGZhY3RvciBhbmFseXNpcyAKIyBtZXRhZGF0YV9ybmFtZXNfbWVyZ2VkX3dpdGhfaW5mb19vcmRlcmQKIyBtZXRhZGF0YV9ybmFtZXNfbWVyZ2VkX3dpdGhfaW5mb19vcmRlcmQkRzZQRF9TVEFUVVMgPC0gZmFjdG9yKG1ldGFkYXRhX3JuYW1lc19tZXJnZWRfd2l0aF9pbmZvX29yZGVyZCRHNlBEX1NUQVRVUykKIyB0YWJsZShtZXRhZGF0YV9ybmFtZXNfbWVyZ2VkX3dpdGhfaW5mb19vcmRlcmQkY2FuY2VyX3R5cGUsIG1ldGFkYXRhX3JuYW1lc19tZXJnZWRfd2l0aF9pbmZvX29yZGVyZCRHNlBEX1NUQVRVUykKIyBtZXRhZGF0YV9ybmFtZXNfbWVyZ2VkX3dpdGhfaW5mb19vcmRlcmQkY2FuY2VyX3R5cGUgPC0gZHJvcGxldmVscyhtZXRhZGF0YV9ybmFtZXNfbWVyZ2VkX3dpdGhfaW5mb19vcmRlcmQkY2FuY2VyX3R5cGUpCiMgbWV0YWRhdGFfcm5hbWVzX21lcmdlZF93aXRoX2luZm9fb3JkZXJkJEc2UERfU1RBVFVTIDwtIGRyb3BsZXZlbHMobWV0YWRhdGFfcm5hbWVzX21lcmdlZF93aXRoX2luZm9fb3JkZXJkJEc2UERfU1RBVFVTKQojIG1ldGFkYXRhX3JuYW1lc19tZXJnZWRfd2l0aF9pbmZvX29yZGVyZApgYGAKCgoKCgoKQWRkIGEgbmV3IGNodW5rIGJ5IGNsaWNraW5nIHRoZSAqSW5zZXJ0IENodW5rKiBidXR0b24gb24gdGhlIHRvb2xiYXIgb3IgYnkgcHJlc3NpbmcgKkNtZCtPcHRpb24rSSouCgpXaGVuIHlvdSBzYXZlIHRoZSBub3RlYm9vaywgYW4gSFRNTCBmaWxlIGNvbnRhaW5pbmcgdGhlIGNvZGUgYW5kIG91dHB1dCB3aWxsIGJlIHNhdmVkIGFsb25nc2lkZSBpdCAoY2xpY2sgdGhlICpQcmV2aWV3KiBidXR0b24gb3IgcHJlc3MgKkNtZCtTaGlmdCtLKiB0byBwcmV2aWV3IHRoZSBIVE1MIGZpbGUpLiAKClRoZSBwcmV2aWV3IHNob3dzIHlvdSBhIHJlbmRlcmVkIEhUTUwgY29weSBvZiB0aGUgY29udGVudHMgb2YgdGhlIGVkaXRvci4gQ29uc2VxdWVudGx5LCB1bmxpa2UgKktuaXQqLCAqUHJldmlldyogZG9lcyBub3QgcnVuIGFueSBSIGNvZGUgY2h1bmtzLiBJbnN0ZWFkLCB0aGUgb3V0cHV0IG9mIHRoZSBjaHVuayB3aGVuIGl0IHdhcyBsYXN0IHJ1biBpbiB0aGUgZWRpdG9yIGlzIGRpc3BsYXllZC4KCg==